var express = require('express')
var router = express.Router()
// var mysql = require('mysql')
// 生成token
const webjwt = require('jsonwebtoken')
const bcrypt = require('bcrypt'); //  加密数字的模块

// 密码强度验证规则
const PASSWORD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}/;

//  从db文件中导入的数据库模块---老的
const db = require("../db/mysql")
const mysql = db;

// 新的

const db_new = require("../db/database");
const { default: axios } = require('axios');
const redisClient = db_new.redisClient;       //获取redis客户端

// 你的小程序配置（从uniCloud控制台获取更安全）
const APP_ID = 'wx2ee3453145ca0eea';
const APP_SECRET = 'be4f8a3189cc890cd4953becc0076fe0';

// 注册 - 使用 async/await-----电脑端
router.post('/register', async function (req, response) {
    var body = req.body;
    let { mobile, password, utype } = body;
    console.log(password)

    // 验证手机号
    if (!/^1[3-9]\d{9}$/.test(mobile)) {
        return response.status(400).json({ code: -1, msg: '手机号不正确', data: {} });
    }

    // 验证密码
    if (!PASSWORD_REGEX.test(password)) {
        return response.status(400).json({ code: -1, msg: '密码必须包含大小写字母和数字，且长度至少8位', data: {} });
    }

    if (!utype) {
        return response.status(400).json({ code: -1, msg: '缺少必要参数', data: {} });
    }

    var ctime = Date.now();
    const [roleName] = await db_new.pool.query(`SELECT name FROM roles WHERE id = ?`, [utype])

    try {
        // 使用 await 等待哈希完成
        const hashedPassword = await bcrypt.hash(password, 10);

        mysql.query('SELECT * FROM users where account = ?', [mobile], async function (error, results) {
            if (results.length > 0) {
                response.json({ data: [], code: -1, msg: '用户已存在，请重新输入' });
            } else {
                mysql.query('INSERT INTO users (account,pwd,utype,ctime) VALUES (?,?,?,?)',
                    [mobile, hashedPassword, utype, ctime],
                    function (err, results) {
                        if (err) {
                            response.json({ code: 1, msg: "操作失败", data: { err } });
                        } else {
                            response.json({
                                code: 0,
                                msg: "注册完成",
                                data: {
                                    account: mobile,
                                    utype: utype,
                                    date: ctime,
                                    roleName: roleName.name
                                }
                            });
                        }
                    });
            }
        });
    } catch (err) {
        response.status(500).json({ code: -1, msg: "服务器错误", data: { err } });
    }
});

// 注册 - 使用 async/await-----手机端
router.post('/register_m', async function (req, response) {
    const body = req.body;
    const { mobile, password, utype, code } = body;
    console.log(password)

    // 验证手机号
    if (!/^1[3-9]\d{9}$/.test(mobile)) {
        return response.status(400).json({ code: -1, msg: '手机号不正确', data: {} });
    }

    // 验证密码
    if (!PASSWORD_REGEX.test(password)) {
        return response.status(400).json({ code: -1, msg: '密码必须包含大小写字母和数字，且长度至少8位', data: {} });
    }

    if (!utype && !code) {
        return response.status(400).json({ code: -1, msg: '缺少必要参数', data: {} });
    }

    try {
        const ctime = Date.now();
        // 获取openid
        const openidRes = await getOpenid(code);
        if (!openidRes.success || !openidRes.openid) {
            await redisClient.incr(`login_attempts:${mobile}`);
            await redisClient.expire(`login_attempts:${mobile}`, 1800); // 30分钟过期
            return res.status(401).json({ code: -1, msg: '微信验证失败', data: {} });
        }

        const openid = openidRes.openid;

        // 使用 await 等待哈希完成
        const hashedPassword = await bcrypt.hash(password, 10);
        const [roleName] = await db_new.pool.query(`SELECT name FROM roles WHERE id = ?`, [utype])

        mysql.query('SELECT * FROM users where account = ? AND openid', [mobile, openid], async function (error, results) {
            if (results.length > 0) {
                response.json({ data: [], code: -1, msg: '用户已存在，请重新输入' });
            } else {
                mysql.query('INSERT INTO users (account,pwd,utype,ctime,openid) VALUES (?,?,?,?,?)',
                    [mobile, hashedPassword, utype, ctime, openid],
                    function (err, results) {
                        if (err) {
                            response.json({ code: 1, msg: "操作失败", data: { err } });
                        } else {

                            response.json({
                                code: 0,
                                msg: "注册完成",
                                data: {
                                    account: mobile,
                                    utype: utype,
                                    date: ctime,
                                    openid: openid,
                                    roleName: roleName.name
                                }
                            });
                        }
                    });
            }
        });
    } catch (err) {
        response.status(500).json({ code: -1, msg: "服务器错误", data: { err } });
    }
});

// // 登录 ---- 原始的
// router.get('/login', async (req, response)=> {
//     var body = req.query;
//     console.log(req.query);

//     let { mobile, pwd } = body;

//     console.log(mobile, pwd);
//     const hashedPassword = await bcrypt.hash(pwd, 10);
//     // 先查询账号是否存在
//     mysql.query('SELECT account, id, logintime FROM users WHERE account = ?', [mobile], async function (error, results) {

//         if (error) {
//             console.log(error);
//             response.json({ code: 1, msg: '数据库查询错误' });
//             return;
//         }
//         if (results.length > 0) {
//             // 如果账号存在的话继续查询账号密码
//             mysql.query('SELECT account, id FROM users WHERE account = ? AND pwd = ?', [mobile, hashedPassword], function (error, results) {
//                 if (error) {
//                     console.log(error);
//                     response.json({ code: 1, msg: '数据库查询错误' });
//                     return;
//                 }
//                 if (results.length > 0) {
//                     let user = results[0];
//                     // 更新登录时间
//                     let now = new Date().getTime(); // 获取当前时间的时间戳，以毫秒为单位
//                     mysql.query('UPDATE users SET logintime = ? WHERE id = ?', [now, user.id], function (error, updateResults) {
//                         if (error) {
//                             console.log(error);
//                             response.json({ code: 1, msg: '数据库更新错误' });
//                             return;
//                         }
//                         // 注意默认情况 Token 必须以 Bearer+空格 开头
//                         const token = 'Bearer ' + webjwt.sign(
//                             {
//                                 uid: user.id,
//                                 account: user.account
//                             },
//                             'pwdxpxweixiu',
//                             {
//                                 expiresIn: 3600 * 24 * 2
//                                 // expiresIn: 1 * 60
//                             }
//                         );
//                         let threeDaysLater = now + 2 * 24 * 60 * 60 * 1000; // 计算三天后的时间戳
//                         // let threeDaysLater = now + 1 * 60 * 1000;

//                         // 检查tokenManage表中是否存在对应的useraccount记录，看看这个用户是否登录过
//                         mysql.query('SELECT token,logintime,expiretime FROM tokenmanage WHERE useraccount = ?',
//                             [user.account],
//                             function (error, tokenResults) {
//                                 console.log(tokenResults[0].logintime, typeof (tokenResults[0].expiretime))
//                                 if (error) {
//                                     console.log(error);
//                                     response.json({ code: 1, msg: '数据库查询错误' });
//                                     return;
//                                 }
//                                 if (tokenResults.length > 0) {
//                                     // 如果当前账号存在token，那就判断登录时间是否超过了过期时间，
//                                     // 如果登录token已经过期了，那就删除当前记录
//                                     if (Number(tokenResults[0].logintime) > Number(tokenResults[0].expiretime)) {
//                                         // 删除+插入添加
//                                         /* mysql.query("DELETE FROM tokenmanage WHERE useraccount = ?", [user.account], (error, resultsexpire) => {
//                                             if (error) console.log(error)
//                                             console.log("token 验证已经过期了，接下来重新添加")
//                                         })
//                                         mysql.query('INSERT INTO tokenmanage (token, logintime, expiretime, useraccount) VALUES (?, ?, ?, ?)',
//                                             [token, now, threeDaysLater, user.account],
//                                             function (error, insertTokenResults) {
//                                                 if (error) {
//                                                     console.log(error);
//                                                 } else {
//                                                     console.log("token表添加成功！");
//                                                 }
//                                         });*/
//                                         // 直接更新 ~~删除+插入添加
//                                         mysql.query("UPDATE tokenmanage SET token = ?, logintime = ?, expiretime = ?, useraccount = ?",
//                                             [token, now, threeDaysLater, user.account],
//                                             (error, updatetokenResults) => {
//                                                 if (error) {
//                                                     console.log(error);
//                                                 } else {
//                                                     console.log("token表更新成功！");
//                                                     response.json({
//                                                         code: 0, msg: "验证更新-登录完成",
//                                                         data: {
//                                                             userid: user.id,
//                                                             user_account: mobile,
//                                                             status: 'ok',
//                                                             token: token
//                                                         }
//                                                     });
//                                                 }
//                                             }
//                                         )
//                                     } else {
//                                         // 如果登录token没有过期了，那就更新当前记录的登录时间改为最新的时间
//                                         mysql.query('UPDATE tokenmanage SET logintime = ? WHERE useraccount = ?',
//                                             [now, user.account],
//                                             function (error, updateTokenResults) {
//                                                 if (error) {
//                                                     console.log(error);
//                                                 } else {
//                                                     console.log("token表的登录时间更新成功！");
//                                                 }
//                                             });
//                                         response.json({
//                                             code: 0, msg: "登录完成",
//                                             data: {
//                                                 userid: user.id,
//                                                 user_account: mobile,
//                                                 status: 'ok',
//                                                 token: tokenResults[0].token
//                                             }
//                                         });
//                                     }
//                                 } else {
//                                     // 如果当前账号不存在token，那就插入一条新记录
//                                     mysql.query('INSERT INTO tokenManage (token, logintime, expiretime, useraccount) VALUES (?, ?, ?, ?)',
//                                         [token, now, threeDaysLater, user.account],
//                                         function (error, insertTokenResults) {
//                                             if (error) {
//                                                 console.log(error);
//                                             } else {
//                                                 console.log("token表添加成功！");
//                                             }
//                                         });
//                                     // 账号密码一致则返回用户需要的数据
//                                     response.json({
//                                         code: 0, msg: "登录完成",
//                                         data: {
//                                             userid: user.id,
//                                             user_account: mobile,
//                                             status: 'ok',
//                                             token: token
//                                         }
//                                     });
//                                 }
//                             });
//                     });
//                 } else {
//                     response.json({
//                         code: 1,
//                         msg: '用户名或密码不正确',
//                     });
//                 }
//             });
//         } else {
//             // 账号不存在则提示：账号不存在，请输入正确的账号
//             response.send({ code: 1, msg: '账号不存在，请输入正确的账号' });
//         }
//     });
// });
// 用户登录尝试次数限制
const MAX_LOGIN_ATTEMPTS = 10;

// 用户登录---- 优化: 使用redis-----电脑端
router.post('/login', async (req, res) => {
    const { mobile, password } = req.body;
    console.log("登录信息：", mobile, password);
    // const hashedPassword = await bcrypt.hash(password, 10);
    // console.log("jiami ++++++++::::::",hashedPassword)
    if (!mobile || !password) {
        return res.status(400).json({ code: -1, msg: '手机号和密码不能为空', data: {} });
    }

    // 检查登录尝试次数
    const attempts = await redisClient.get(`login_attempts:${mobile}`);
    if (attempts >= MAX_LOGIN_ATTEMPTS) {
        return res.status(429).json({ code: -1, msg: '登录尝试次数过多，请稍后再试', data: {} });
    }

    try {
        // 从数据库获取用户信息
        // const [users] = await db_new.pool.query(
        //     'SELECT * FROM users WHERE account = ?',
        //     [mobile]
        // );
        // const [roleName] = await db_new.pool.query(`SELECT name FROM roles WHERE id = ?`, [utype])
        // // 查询用户
        const [users] = await db_new.pool.query(
            `SELECT 
                users.uname, users.account, users.utype, users.pwd, users.picture AS avatar, roles.name AS roleName
            FROM users 
            LEFT JOIN roles ON roles.id = users.utype
            WHERE users.account = ?`,
            [mobile]
        );

        console.log("用户信息：", users);

        if (users.length === 0) {
            // 当你的邮箱或密码错误的时候，在这里把mobile存到redis数据库，作为当前邮箱的请求登录次数，在上面登录尝试次数中起到关键作用
            await redisClient.incr(`login_attempts:${mobile}`);
            return res.status(401).json({ code: -1, msg: '邮箱或密码错误', data: {} });
        }

        const user = users[0];
        console.log("数据库中的Miami:", user.pwd)
        const passwordMatch = await bcrypt.compare(password, user.pwd);
        console.log("密码匹配：", passwordMatch);

        // 密码不匹配，增加尝试次数并返回错误提示
        // 密码验证失败
        if (!passwordMatch) {
            await redisClient.incr(`login_attempts:${mobile}`);
            return res.status(401).json({ code: -1, msg: '密码错误，请重试', data: {} });
        }

        // 用户信息
        const userInfo = {
            id: user.id,
            username: user.uname,
            phone: user.account,
            role: user.utype,
            roleName: user.roleName,
            avatar: user.avatar
        };
        // 更新用户的登录时间
        let nowTime = new Date()
        let sql = `
            UPDATE users SET logintime = ?
            WHERE id = ?
        `
        const [results] = await db_new.pool.query(sql, [nowTime, user.id])
        // 生成 JWT
        const token = webjwt.sign(
            userInfo,
            "pwdxpxweixiu",
            { expiresIn: '24h' } // 24小时后过期
            
        );
        res.json({ code: 0, msg: '登录成功', data: { token, userInfo } });
    } catch (error) {
        console.error("服务器登录异常：", error);
        res.status(500).json({ code: -1, msg: '登录失败', data: {} });
    }

    // 登录成功时清除尝试次数
    await redisClient.del(`login_attempts:${mobile}`);
});

// 用户登录---- 优化: 使用redis-----手机端
router.post('/login_m', async (req, res) => {
    const { mobile, password, code } = req.body;
    console.log(req.body)

    if (!mobile || !password || !code) {
        return res.status(400).json({ code: -1, msg: '手机号、密码和验证码不能为空', data: {} });
    }

    // 检查登录尝试次数
    const attempts = await redisClient.get(`login_attempts:${mobile}`);
    if (attempts >= MAX_LOGIN_ATTEMPTS) {
        const ttl = await redisClient.ttl(`login_attempts:${mobile}`);
        return res.status(429).json({
            code: -1,
            msg: `登录尝试次数过多，请${Math.ceil(ttl / 60)}分钟后再试`,
            data: {}
        });
    }

    try {
        // 获取openid
        const openidRes = await getOpenid(code);
        if (!openidRes.success || !openidRes.openid) {
            await redisClient.incr(`login_attempts:${mobile}`);
            await redisClient.expire(`login_attempts:${mobile}`, 1800); // 30分钟过期
            return res.status(401).json({ code: -1, msg: '微信验证失败', data: {} });
        }

        const openid = openidRes.openid;

        // 查询用户
        const [users] = await db_new.pool.query(
            `SELECT 
                users.id, users.uname, users.account, users.utype, users.pwd, users.picture AS avatar, roles.name AS roleName
            FROM users 
            LEFT JOIN roles ON roles.id = users.utype
            WHERE users.account = ? AND users.openid = ?`,
            [mobile, openid]
        );
        // const [roleName] = await db_new.pool.query(`SELECT name FROM roles WHERE id = ?`, [user.utype])

        if (users.length === 0) {
            await redisClient.incr(`login_attempts:${mobile}`);
            await redisClient.expire(`login_attempts:${mobile}`, 1800);
            return res.status(401).json({ code: -1, msg: '用户不存在或未绑定微信', data: {} });
        }
        console.log("sql中=的数据：：：：",users)
        const user = users[0];
        const passwordMatch = await bcrypt.compare(password, user.pwd);

        if (!passwordMatch) {
            await redisClient.incr(`login_attempts:${mobile}`);
            await redisClient.expire(`login_attempts:${mobile}`, 1800);
            return res.status(401).json({ code: -1, msg: '密码错误', data: {} });
        }

        // 登录成功逻辑
        await redisClient.del(`login_attempts:${mobile}`); // 清除尝试次数

        // 更新登录时间
        const nowTime = new Date();
        await db_new.pool.query('UPDATE users SET logintime = ? WHERE id = ?', [nowTime, user.id]);

        // 生成token
        const userInfo = {
            id: user.id,
            username: user.uname,
            phone: user.account,
            role: user.utype,
            roleName: user.roleName,
            avatar: user.avatar
        };

        const token = webjwt.sign(
            userInfo,
            "pwdxpxweixiu",
            { expiresIn: '24h' }
        );

        return res.json({ code: 0, msg: '登录成功', data: { token, userInfo } });

    } catch (error) {
        console.error("登录异常:", error);
        return res.status(500).json({ code: -1, msg: '服务器错误', data: {} });
    }
});

// 获取openid函数优化
const getOpenid = async (code) => {
    try {
        const response = await axios.get(
            `https://api.weixin.qq.com/sns/jscode2session?appid=${APP_ID}&secret=${APP_SECRET}&js_code=${code}&grant_type=authorization_code`
        );

        // 微信接口返回错误时也会返回200状态码，但有errcode字段
        if (response.data.errcode) {
            return {
                success: false,
                error: response.data
            };
        }

        return {
            success: true,
            openid: response.data.openid,
            session_key: response.data.session_key
        };
    } catch (error) {
        console.error("获取openid失败:", error);
        return {
            success: false,
            error: error.response?.data || error.message
        };
    }
};

// 获取全部用户角色
router.get("/allRole", async (req, res) => {
    try {
        const [results] = await db_new.pool.query(`
            SELECT name as label,id as value FROM roles
        `)
        return res.json({
            code: 0,
            msg: "获取全部用户角色成功",
            data: results
        })
    } catch (error) {
        console.log("获取全部用户角色")
        return res.status(500).json({
            code: -1,
            msg: "获取全部用户角色失败"
        })
    }
})

// 退出登录的接口
// router.get('/logout', function (req, res) {
//     // 从请求头中获取token
//     const token = req.headers['authorization'] || req.headers['Authorization'];
//     if (!token) {
//         return res.status(401).json({ code: 1, msg: '未提供token', data: {} });
//     }
//     try {
//         // 验证token并获取uid
//         const decoded = webjwt.verify(token.replace('Bearer ', ''), 'pwdxpx');
//         const uid = decoded.uid;
//         console.log(uid)
//         // 将token添加到黑名单中
//         tokenBlacklist[token] = true;

//         // 返回成功响应
//         res.json({
//             code: 0,
//             msg: '已退出登录',
//             data: {}
//         });
//     } catch (error) {
//         // 如果token验证失败或已过期
//         res.status(401).json({ code: 1, msg: 'token无效', data: {} });
//     }
// });
//退出
// old
// router.grt('/logout', function (req, res, next) {
//     // 从请求头中获取Authorization字段，并提取token
//     const authHeader = req.headers.authorization;
//     const token = authHeader ? authHeader.split(' ')[1] : null; // 提取token
//     if (!token) {
//         return res.status(401).json({ msg: "未提供有效的token", code: 401 });
//     }
//     console.log(token);
//     // 先通过请求头中提供的token，去数据表中根据token字段查找是否存在该记录
//     let sqltoken = `SELECT useraccount, logintime, expiretime FROM tokenmanage WHERE token = ?`;
//     mysql.query(sqltoken, [token], (error, results) => {
//         if (error) {
//             console.log(error);
//             return res.status(500).json({ msg: "服务器错误", code: 500 });
//         } else {
//             // 如果查找语句查出结果代表此token已经存在记录，要做到退出就将此token对应的记录删除即可
//             if (results.length === 0) {
//                 return res.status(404).json({ msg: "未找到token", code: 404 });
//             }
//             // 假设你只想返回一个退出成功的消息，而不是整个results对象
//             var msg = { "msg": "退出成功", code: 0 };
//             // 删除tokenmanage表中对应的记录
//             let deleteSql = `DELETE FROM tokenmanage WHERE token = ?`;
//             mysql.query(deleteSql, [token], (deleteError, deleteResults) => {
//                 if (deleteError) {
//                     console.log(deleteError);
//                     return res.status(500).json({ msg: "删除token失败", code: 500 });
//                 }
//                 // 如果删除成功，返回成功消息
//                 res.json(msg);
//             });
//         }
//     });
// });

// 用户退出登录


router.post('/logout', async (req, res) => {
    try {
        const token = req.headers['authorization']?.split(' ')[1];
        if (!token) {
            return res.status(400).json({ code: -1, msg: '未提供token', data: {} });
        }

        try {
            // 验证token是否有效
            const decoded = jwt.verify(token, "pwdxpxweixiu");
            // 将token加入黑名单，过期时间与token的过期时间一致
            const tokenExp = decoded.exp;
            const now = Math.floor(Date.now() / 1000);
            const ttl = tokenExp - now;

            if (ttl > 0) {
                // 将token加入Redis黑名单
                await redisClient.setEx(`blacklist:${token}`, ttl, 'true');
            }

            res.json({ code: 0, msg: '登出成功', data: {} });
        } catch (err) {
            // token已过期或无效
            res.json({ code: 0, msg: '登出成功', data: {} });
        }
    } catch (error) {
        console.error('登出失败:', error);
        res.status(500).json({ code: -1, msg: '登出失败', data: {} });
    }
});
module.exports = router;